import React, {FC, useCallback, useEffect, useMemo, useRef, useState} from "react";
import "./css/ColAdd.less";
import {useTranslation} from "react-i18next";
import useStateRef from "../../../customUse/useStateRef";
import {Button, Input, InputNumber, Radio, Switch, Table} from "antd";
import {addOkModal, closeModal} from "../../../services/ModalService";
import {AxiosGet, AxiosSer} from "../../../services/HttpService";
import {getFormView} from "../../../services/ViewService";
import useThrottle from "../../../customUse/useThrottle";
import GlobalIcon from "../../../global/GlobalIcon.tsx";
import BaseForm from "../../../module/form/BaseForm.tsx";
import {showMessage} from "../../../reducer/MsgReducer.tsx";

interface ColAddProps {
    modalKey: string,
    type: string,
    view?: string,
    flowData: any[]
}

const ColAdd: FC<ColAddProps> = (props) => {
    const {t} = useTranslation();

    const formRef = useRef();
    const viewRef = useRef([]);
    const dataRef = useRef([]);

    const [view, setView] = useStateRef([], viewRef),
        [columns, setColumns] = useState<any[]>([]),
        [dataSource, setDataSource] = useStateRef([], dataRef);

    const isCreate: Function = useCallback(() => {
        return props.type === "create";
    }, [props.type]);

    const isCopy: Function = useCallback(() => {
        return props.type === "copy";
    }, [props.type]);

    const handleChange: Function = (index: number, fields: string[], value: any) => {
        let row = [...dataRef.current];
        let node: any = row[index];
        fields.forEach(field => {
            node[field] = value[field];
        });
        setDataSource(row);
    };

    const handleChangeIndex: Function = (index: number, change: number) => {
        let targetI: number = index + change,
            row: any = [...dataRef.current],
            tempIRow: any = row[index];
        if (targetI > row.length - 1) {
            return;
        }

        row.splice(index, 1, row[targetI]);
        row.splice(targetI, 1, tempIRow);

        setDataSource(row);
    };

    const handleDelete: Function = (index: number) => {
        let row = [...dataRef.current];
        row.splice(index, 1);
        setDataSource(row);
    };

    const handleAdd: Function = useCallback(() => {
        let newNode = {
            id: Math.random(),
            optType: "add",
        };
        setDataSource([...dataSource, newNode]);
    }, [dataSource]);

    const onOk: Function = useThrottle(async () => {
        if (!formRef.current) {
            return;
        }
        let values = await formRef.current.validateFields();
        let requireAttrs: string[] = ["zhCn", "usEn", "ptBr", "field"];
        for (let item of dataRef.current) {
            for (let attrName of requireAttrs) {
                if (!item[attrName]) {
                    showMessage({
                        type: "error",
                        msg: t("notNullValue")
                    })
                    return;
                }
            }
        }
        let submitList: any[] = [], params: any = {
            type: "table",
            ...values
        };
        dataRef.current.forEach((item: any, index: number) => {
            submitList.push({
                id: item.optType === "add" ? undefined : item.id,
                zhCn: item.zhCn,
                usEn: item.usEn,
                ptBr: item.ptBr,
                field: item.field,
                sortable: item.sortable ? 1 : 0,
                fixed: item.fixed || "",
                width: item.width,
                orderNo: index + 1,
                config: item.config
            })
        });
        params["containColumns"] = submitList;
        let result: any = await AxiosSer("/sf-drs/platform/view/saveSystemTableView", "POST", params);
        result.code == "1" && await closeModal(props.modalKey, async () => {
            return {data: params, ...result};
        })

    }, 2000, [dataSource]);

    const createEditInput: Function = useCallback((field: string) => {
        return (text: string, node: any, index: number) => {
            return <Input style={{width: "100%"}} value={text} onChange={e => {
                handleChange(index, [field], {[field]: e.target.value})
            }}/>;
        }
    }, []);

    const createEditInputNumber: Function = useCallback((field: string) => {
        return (text: string, node: any, index: number) => {
            return <InputNumber style={{width: "100%"}} value={text} onChange={value => {
                handleChange(index, [field], {[field]: value});
            }}/>;
        }
    }, []);

    const createEditInputTextArea: Function = useCallback((field: string) => {
        return (text: string, node: any, index: number) => {
            return <Input.TextArea style={{width: "100%"}} value={text} onChange={e => {
                handleChange(index, [field], {[field]: e.target.value})
            }}/>;
        }
    }, []);

    const createEditSwitch: Function = useCallback((field: string) => {
        return (text: boolean, node: any, index: number) => {
            return <Switch style={{width: "100%"}} checked={text} onChange={value => {
                handleChange(index, [field], {[field]: value});
            }}/>;
        }
    }, []);

    const createEditRadio: Function = useCallback((field: string) => {
        return (text: boolean, node: any, index: number) => {
            return <Radio.Group style={{width: "100%"}} size={"small"} value={text === undefined ? "" : text}
                                onChange={e => {
                                    handleChange(index, [field], {[field]: e.target.value})
                                }}>
                <Radio.Button value="left">{t("left")}</
                    Radio.Button>
                < Radio.Button
                    value=""> {t("none"
                )
                }</Radio.Button>
                <Radio.Button value="right">{t("right")}</Radio.Button>
            </Radio.Group>;
        }
    }, []);

    const createOpt: Function = useCallback(() => {
        return (text: string, node: any, i: number) => {
            return (<Button.Group>
                <Button icon={<GlobalIcon name="icon-put-away"/>} onClick={() => handleChangeIndex(i, -1)}/>
                <Button icon={<GlobalIcon name="icon-launch"/>} onClick={() => handleChangeIndex(i, 1)}/>
                <Button icon={<GlobalIcon name="icon-delete"/>} onClick={() => handleDelete(i)}/>
            </Button.Group>)
        }
    }, []);

    const loadView: Function = useCallback(async () => {
        const {view = "form_view_create", flowData = []}: { view?: string, flowData: any[] } = props;
        let editData: any = {};
        if (props.type !== "create") {
            editData = {
                id: isCopy() ? undefined : flowData[0].id,
                name: flowData[0].name,
                config: flowData[0].config,
                description: flowData[0].description
            }
        }
        let result: any = await getFormView(view, editData);
        setView(result.form);

    }, [props.view, props.type, props.flowData]);

    const loadColumns: Function = useCallback(async () => {
        let columns: any[] = [];
        let {form = []}: { form: any } = await getFormView("form_view_col_create");
        columns = form.map((item: any) => {
            let renderCom: Function = createEditInput(item.field),
                width = 150;

            if (item.field === "width") {
                renderCom = createEditInputNumber(item.field);
            } else if (item.field === "sortable") {
                width = 50;
                renderCom = createEditSwitch(item.field);
            } else if (item.field === "fixed") {
                width = 180;
                renderCom = createEditRadio(item.field);
            } else if (item.field === "config") {
                renderCom = createEditInputTextArea(item.field);
            }

            return {
                title: <>{item.title} {item.required ? <span style={{color: "red"}}>*</span> : null}</>,
                dataIndex: item.field,
                align: "center",
                width: width,
                render: renderCom
            }
        });
        columns.push({
            title: t("opt"),
            dataIndex: "opt",
            width: 120,
            render: createOpt()
        });
        setColumns(columns);
    }, []);

    const loadData: Function = useCallback(async () => {
        let row: any[] = [];
        if (isCreate()) {
            row = [];
        } else {
            const {flowData = []}: { flowData: any[] } = props;
            let {data}: {
                data: any
            } = await AxiosGet("/sf-drs/platform/view/getSystemTableViewDetails", {viewName: flowData[0].name});
            row = [...data.alternativeColumns, ...data.containColumns].map((item: any) => {
                return {
                    id: isCopy() ? undefined : item.id,
                    zhCn: item.zhCn,
                    usEn: item.usEn,
                    ptBr: item.ptBr,
                    field: item.field,
                    sortable: !!item.sortable,
                    fixed: item.fixed || "",
                    width: item.width,
                    config: item.config
                }
            });
        }

        setDataSource(row);
    }, [props]);

    const init: Function = useCallback(async () => {
        await loadView();
        loadColumns();
        loadData();
    }, []);

    useEffect(() => {
        init();
    }, []);

    useEffect(() => {
        addOkModal(props.modalKey, onOk);
    }, []);

    const renderForm = useMemo(() => {
        return (
            <div className="sf_core_view_col_add_form">
                <BaseForm
                    init={formRef}
                    formItemLayout={2}
                    view={view}
                />
            </div>
        )
    }, [view, props]);

    const renderTable = useMemo(() => {
        return (
            <div className="sf_core_view_col_add_table">
                <Table
                    columns={columns}
                    dataSource={dataRef.current}
                    pagination={false}
                    size={'small'}
                    bordered={true}
                    rowKey={'id'}
                    footer={() => {
                        return (
                            <div className="sf_core_view_col_add_table_footer">
                                <Button onClick={handleAdd} icon={<GlobalIcon style={{fontSize: 10}}
                                                                              name="icon-create"/>}>{t("add")}</Button>
                            </div>
                        )
                    }}
                />
            </div>
        )
    }, [columns, dataSource, props]);

    const renderColAdd = useMemo(() => {
        return (
            <div className="sf_core_view_col_add">
                {renderForm}
                {renderTable}
            </div>
        )
    }, [view, columns, dataSource, props]);

    return (renderColAdd);
};

export default ColAdd;